package com.app.xinfadi.util;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.StateListDrawable;
import android.net.Uri;
import android.text.TextUtils;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class BitmapUtils {
    private static final String TAG = BitmapUtils.class.getSimpleName();

    public static Bitmap duplicateBitmap(Bitmap bmpSrc) {
        if (null == bmpSrc) {
            return null;
        }

        int bmpSrcWidth = bmpSrc.getWidth();
        int bmpSrcHeight = bmpSrc.getHeight();

        Bitmap bmpDest = Bitmap.createBitmap(bmpSrcWidth, bmpSrcHeight, Config.ARGB_4444);
        if (null != bmpDest) {
            Canvas canvas = new Canvas(bmpDest);
            final Rect rect = new Rect(0, 0, bmpSrcWidth, bmpSrcHeight);

            canvas.drawBitmap(bmpSrc, rect, rect, null);
        }

        return bmpDest;
    }

    public static Bitmap createBitmap(int w, int h) {
        int bmpSrcWidth = w;
        int bmpSrcHeight = h;
        Bitmap bmpDest = Bitmap.createBitmap(bmpSrcWidth, bmpSrcHeight, Config.ARGB_8888);
        if (null != bmpDest) {
            Canvas canvas = new Canvas(bmpDest);
            canvas.drawColor(Color.TRANSPARENT);
            final Rect rect = new Rect(0, 0, bmpSrcWidth, bmpSrcHeight);
            canvas.drawBitmap(bmpDest, rect, rect, null);
            return bmpDest;
        } else {
            return null;
        }
    }

    /**
     * 创建一个图片
     *
     * @param contentColor 内部填充颜色
     * @param strokeColor  描边颜色
     * @param radius       圆角
     */
    public static GradientDrawable createDrawable(int contentColor, int strokeColor, int radius) {
        GradientDrawable drawable = new GradientDrawable(); // 生成Shape
        drawable.setGradientType(GradientDrawable.RECTANGLE); // 设置矩形
        drawable.setColor(contentColor);// 内容区域的颜色
        drawable.setStroke(1, strokeColor); // 四周描边,描边后四角真正为圆角，不会出现黑色阴影。如果父窗体是可以滑动的，需要把父View设置setScrollCache(false)
        drawable.setCornerRadius(radius); // 设置四角都为圆角
        return drawable;
    }

    /**
     * 创建一个图片选择器
     *
     * @param normalState  普通状态的图片
     * @param pressedState 按压状态的图片
     */
    public static StateListDrawable createSelector(Drawable normalState, Drawable pressedState) {
        StateListDrawable bg = new StateListDrawable();
        bg.addState(new int[]{android.R.attr.state_pressed, android.R.attr.state_enabled}, pressedState);
        bg.addState(new int[]{android.R.attr.state_enabled}, normalState);
        bg.addState(new int[]{}, normalState);
        return bg;
    }

    public static Bitmap drawableToBitmap(Drawable drawable) {

        Bitmap bitmap = Bitmap.createBitmap(

                drawable.getIntrinsicWidth(),

                drawable.getIntrinsicHeight(),

                drawable.getOpacity() != PixelFormat.OPAQUE ? Config.ARGB_8888

                        : Config.RGB_565);

        Canvas canvas = new Canvas(bitmap);

        // canvas.setBitmap(bitmap);

        drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());

        drawable.draw(canvas);

        return bitmap;

    }

    /**
     * 保存图片到本地
     *
     * @param path
     * @param drawable
     */
    public static boolean saveToSdCard(String path, Drawable drawable) {
        return saveToSdCard(path, drawableToBitmap(drawable));
    }

    /**
     * 保存图片到本地
     *
     * @param path
     * @param bitmap
     */
    public static boolean saveToSdCard(String path, Bitmap bitmap) {
        LogUtil.e(TAG, "saveToSdCard---path:" + path);
        boolean savedSuccessfully = false;
        File file = null;
        if (bitmap != null && !TextUtils.isEmpty(path)) {
            try {
                file = new File(path);
                if (file.exists()) {
                    //如果存在相同的图片则删除
                    file.delete();
                }
                file.createNewFile();
                BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
                // 30 是压缩率，表示压缩70%; 如果不压缩是100，表示压缩率为0
                savedSuccessfully = bitmap.compress(Bitmap.CompressFormat.PNG, 100, bos);
                bos.flush();
                bos.close();
                return true;
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (file != null && !savedSuccessfully) {
                    file.delete();
                }
                if (!bitmap.isRecycled()) {
                    LogUtil.d("saveToSdCard ", "save释放");
                    bitmap.recycle();
                    bitmap = null;
                }

            }
        }
        return false;
    }

    public static Bitmap loadFromSdCard(String filePath) {
        File file = new File(filePath);
        Bitmap bmp = null;
        try {
            FileInputStream fis = new FileInputStream(file);
            bmp = BitmapFactory.decodeStream(fis).copy(Config.ARGB_8888, true);
            if (bmp != null) {
                return bmp;
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Bitmap loadFromSdCard(String filePath, int w, int h) {
        Bitmap bitmap;
        BitmapFactory.Options op = new BitmapFactory.Options();
        op.inJustDecodeBounds = true;
        bitmap = BitmapFactory.decodeFile(filePath, op);
        int wRatio = (int) Math.ceil(op.outWidth / (float) w);
        int hRatio = (int) Math.ceil(op.outHeight / (float) h);
        // 如果超出指定大小，则缩小相应的比例
        if (wRatio > 1 && hRatio > 1) {
            if (wRatio > hRatio) {
                op.inSampleSize = wRatio;
            } else {
                op.inSampleSize = hRatio;
            }
        }
        // opts.inSampleSize = computeSampleSize(opts, -1, 128*128);
        op.inJustDecodeBounds = false;
        try {
            bitmap = BitmapFactory.decodeFile(filePath, op);
            // imageView.setImageBitmap(bmp);
        } catch (OutOfMemoryError err) {

        }
        return bitmap;
    }

    public static Bitmap loadFromSdCard(Context context, Uri filePath, int w, int h) throws FileNotFoundException {
        Bitmap bitmap;
        BitmapFactory.Options op = new BitmapFactory.Options();
        op.inJustDecodeBounds = true;
        bitmap = BitmapFactory.decodeStream(context.getContentResolver().openInputStream(filePath), null, op);
        int wRatio = (int) Math.ceil(op.outWidth / (float) w);
        int hRatio = (int) Math.ceil(op.outHeight / (float) h);
        // 如果超出指定大小，则缩小相应的比例
        if (wRatio > 1 && hRatio > 1) {
            if (wRatio > hRatio) {
                op.inSampleSize = wRatio;
            } else {
                op.inSampleSize = hRatio;
            }
        }
        // opts.inSampleSize = computeSampleSize(opts, -1, 128*128);
        op.inJustDecodeBounds = false;
        try {
            bitmap = BitmapFactory.decodeStream(context.getContentResolver().openInputStream(filePath), null, op);
            // imageView.setImageBitmap(bmp);
        } catch (OutOfMemoryError err) {

        }
        return bitmap;
    }

    public static Bitmap loadFromSdCard2(String filePath) {
        Bitmap bitmap;
        BitmapFactory.Options op = new BitmapFactory.Options();
        op.inJustDecodeBounds = true;
        bitmap = BitmapFactory.decodeFile(filePath, op);
        op.inSampleSize = computeSampleSize(op, -1, 310 * 280);
        op.inJustDecodeBounds = false;
        try {
            bitmap = BitmapFactory.decodeFile(filePath, op);
        } catch (OutOfMemoryError err) {

        }
        return bitmap;
    }

    public static Bitmap decodeFile(File f, int bmpsize) {
        if (f == null )
            return null;

        try {
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            o.inPreferredConfig = Config.ARGB_8888;
            BitmapFactory.decodeStream(new FileInputStream(f), null, o);
            final int REQUIRED_SIZE = bmpsize;
            int width_tmp = o.outWidth, height_tmp = o.outHeight;
            int scale = 1;
            if (width_tmp > REQUIRED_SIZE || height_tmp > REQUIRED_SIZE) {
                if (width_tmp > height_tmp) {
                    scale = width_tmp / REQUIRED_SIZE;
                } else {
                    scale = height_tmp / REQUIRED_SIZE;
                }
            }
            // decode with inSampleSize

            BitmapFactory.Options o2 = new BitmapFactory.Options();

            o2.inSampleSize = scale;
            o2.inPreferredConfig = Config.ARGB_8888;

            Bitmap bmp = BitmapFactory.decodeStream(new FileInputStream(f),
                    null, o2);
            return bmp;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }


    public static int computeSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) {
        int initialSize = computeInitialSampleSize(options, minSideLength, maxNumOfPixels);

        int roundedSize;
        if (initialSize <= 8) {
            roundedSize = 1;
            while (roundedSize < initialSize) {
                roundedSize <<= 1;
            }
        } else {
            roundedSize = (initialSize + 7) / 8 * 8;
        }

        return roundedSize;
    }

    private static int computeInitialSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) {
        double w = options.outWidth;
        double h = options.outHeight;

        int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels));
        int upperBound = (minSideLength == -1) ? 128 : (int) Math.min(Math.floor(w / minSideLength),
                Math.floor(h / minSideLength));

        if (upperBound < lowerBound) {
            // return the larger one when there is no overlapping zone.
            return lowerBound;
        }

        if ((maxNumOfPixels == -1) && (minSideLength == -1)) {
            return 1;
        } else if (minSideLength == -1) {
            return lowerBound;
        } else {
            return upperBound;
        }
    }

    /* 复制的 */
    public static Bitmap duplicateBitmap(Bitmap bmpSrc, int width, int height) {
        if (null == bmpSrc) {
            return null;
        }

        int bmpSrcWidth = bmpSrc.getWidth();
        int bmpSrcHeight = bmpSrc.getHeight();

        Bitmap bmpDest = Bitmap.createBitmap(width, height, Config.ARGB_4444);
        if (null != bmpDest) {
            Canvas canvas = new Canvas(bmpDest);
            Rect viewRect = new Rect();
            final Rect rect = new Rect(0, 0, bmpSrcWidth, bmpSrcHeight);
            if (bmpSrcWidth <= width && bmpSrcHeight <= height) {
                viewRect.set(rect);
            } else if (bmpSrcHeight > height && bmpSrcWidth <= width) {
                viewRect.set(0, 0, bmpSrcWidth, height);
            } else if (bmpSrcHeight <= height && bmpSrcWidth > width) {
                viewRect.set(0, 0, width, bmpSrcWidth);
            } else if (bmpSrcHeight > height && bmpSrcWidth > width) {
                viewRect.set(0, 0, width, height);
            }
            canvas.drawBitmap(bmpSrc, rect, viewRect, null);
        }

        return bmpDest;
    }
}
